<%-- 
Given a URL
      o Fetch the URL
      o Transform all links to use this redirect
      o Log where we came from and where we are going

   1. Output some JavaScript at the very top.
         o The first goal is to transform all links and URL references 
           to be absolute references when the page is loaded.
         o The second goal is to redirect all href links to use 
           the proxy.jsp page.
   2. Fetch the URL via Java.
         o Take the URL specified by the "replace" parameter.
         o Load in the URL, spit it back out.

Here is part of a sample logfile:

170     0 1     200 -1 http://www.cs.berkeley.edu
2664    1 2     200 15 http://www.eecs.berkeley.edu/Resguide/soda.staff.shtml
5889    2 3     200 8 http://www.eecs.berkeley.edu/Students/Grad/Affairs/CS/
116718  1 4     200 27 http://www.cs.berkeley.edu/Students/newsgroups.shtml
118450  4 5     200 9 http://www.cs.berkeley.edu/Newspages/


Annotated, here is what it means:

Time From To   HTTP Link# URL
170     0 1     200 -1 http://www.cs.berkeley.edu
2664    1 2     200 15 http://www.eecs.berkeley.edu/Resguide/soda.staff.shtml
5889    2 3     200 8 http://www.eecs.berkeley.edu/Students/Grad/Affairs/CS/
116718  1 4     200 27 http://www.cs.berkeley.edu/Students/newsgroups.shtml
118450  4 5     200 9 http://www.cs.berkeley.edu/Newspages/


Time  - Time (in msec) that the page was requested, where 0 is the start time.
From  - The transaction ID# of the page where we just came from.
        You can think of the transaction ID# as the Nth page we viewed.
To    - The current transaction ID#. Pretty much always increments up by one.
HTTP  - The HTTP response code. 200 means ok, 404 means not found.
Link# - The person clicked on the Nth link on the previous page to get here,
        where 0 is the starting link.
URL   - The current URL we are at.


--%>
<%--                                                                        --%>
<%--  --------------------------------------------------------------------- --%>
<%--                                                                        --%>
<%@ page import="java.io.*"                                                   %>
<%@ page import="java.net.*"                                                  %>
<%@ page import="edu.berkeley.guir.webquilt.*"                                %>
<%! String strReplace; // the URL to go to                                    %>
<%! String strBase;    // the base URL to go to                               %>
<%! String strFromTID; // the transaction ID of request                       %>
<%! String strLinkID;  // the link ID, ie the Nth link on the page            %>
<%! String strSvrA;    // base server URL for webquilt                        %>
<%! String strSvrB;    // alt URL for the server                              %>
<%! String strURI;     // URI path to redirect dir                            %>
<%! String strPort;    // the server port number                              %>
<%! int    nextTID;    // the next transaction ID to use                      %>
<% 
    //// 0. Init some request constants.
    strURI     = request.getRequestURI().substring(0,
                                  request.getRequestURI().lastIndexOf("/"));

    //// 0. Init one-time session constants.
    Object objInit = session.getValue("INIT");
    if (objInit == null) {
       //// 0.1. Figure out the name of the machine we are on.
       strSvrA    = "http://" + request.getServerName();
       strPort    = ":" + request.getServerPort();
       if (strPort.equals(":80")) {
          strPort = "";
       }
       strSvrA    += strPort;
       strSvrB     = strSvrA + strURI + "/";

       //// 0.2. Make sure the server name is lower case. Potential bug if
       ////      the server name isn't, since we do string comparisons.
       strSvrA     = strSvrA.toLowerCase();
       strSvrB     = strSvrB.toLowerCase();

       //// 0.3. Store the server values.
       session.putValue("SVRA", strSvrA);
       session.putValue("SVRB", strSvrB);

       //// 0.4. Initialize the session transaction ID.
       session.putValue("TID", new Integer(0));

       //// 0.5. Initialize the session start time.
       session.putValue("STARTTIME", new Long(System.currentTimeMillis()));

       //// 0.6. Set the init flag.
       session.putValue("INIT", Boolean.TRUE);

       //// 0.7. Initialize the read buffer.
       session.putValue("BUFFER", new byte[8192]);
    }

    //// 1.1. Get the server name.
    strSvrA = (String) session.getValue("SVRA");
    strSvrB = (String) session.getValue("SVRB");

    //// 1.2. Get the next session transaction ID.
    Integer nextTIDInteger = (Integer) session.getValue("TID");

    //// 1.3. Put in the session start time.
    Long dTime = (Long) session.getValue("STARTTIME");


    //// 2. Get parameters from the URL.
    strReplace = ((String) request.getParameter("replace"));
    strReplace = WebQuiltLib.trimReplaceParameter(strReplace);

    strFromTID = (String) request.getParameter("tid");
    if (strFromTID == null) {
       strFromTID = "0";
    }
    strLinkID  = (String) request.getParameter("linkid");
    if (strLinkID == null) {
       strLinkID = "-1";
    }


    //// 3. Check for replace parameter.
    ////    If the replace parameter doesn't exist, then show a default page.
    if (strReplace == null) {
      %> <%@ include file="StartPage.html" %> <%
          return;
    } 
    //// Doesn't account for https connections. Can we support those?
    if (!strReplace.startsWith("http://")) {
       strReplace = "http://" + strReplace;
    }


    //// 4. Generate the base of the page.
    strBase = WebQuiltLib.generateBaseHref(strReplace);


    //// 5. Set the from tid value to be max of current TID and next TID,
    ////    just in case someone bookmarked the URL or if someone is
    ////    trying to hack the system.
    int fromTIDval;
    try {
       fromTIDval = Integer.parseInt(strFromTID);
    }
    catch (Exception e) {
       fromTIDval = 0;
    }


    //// 6. Increment the next session transaction ID.
    ////    Store the next session transaction ID.
    nextTID = Math.max(nextTIDInteger.intValue(), fromTIDval) + 1;
    session.putValue("TID", new Integer(nextTID));


    //// 7. Used to be code to force refreshes, but this leads
    ////    to problems since the refreshed URL will have the wrong
    ////    FROM TID# (ie it thinks it came from a different page).
    ////    Since we can't change the FROM TID, just ignore this.

/*
    //// 8.1. Set response. First set HTTP1.1 headers.
    HttpServletResponse res = (HttpServletResponse) response;
    res.setHeader("Cache-Control", "must-revalidate");
    res.setHeader("Cache-Control", "max-age=5");
    res.setHeader("Cache-Control", "no-cache");

    //// 8.2. Now set HTTP1.0 headers.
    res.setHeader("Expires", "0");
    res.setHeader("Pragma",  "no-cache");
*/

%>
<%--                                                                        --%>
<%--  --------------------------------------------------------------------- --%>
<%--                                                                        --%>
<BASE HREF="<%= strBase %>">
<HTML>
<BODY onLoad="modifyAllLinks()";>

<!--
<HEAD>
   <META HTTP-EQUIV="expires" CONTENT="0">
   <META HTTP-EQUIV="pragma"  CONTENT="no-cache">
</HEAD>
-->

<script language="JavaScript">

<!--                                       -->
<!-- Method called when page is loaded     -->
<!-- Just proxy all image and href links   -->
function modifyAllLinks() {
   proxyImages();
   proxyHrefLinks();
   proxyForms();
}


<!--                                       -->
<!-- Proxy images so that we can save them -->
function proxyImages() {
}


<!--                                           -->
<!-- Proxy href links so that we can save them -->
function proxyHrefLinks() {
   var svr     = '<%= strSvrA    %>';
   var tid     = '<%= nextTID    %>';

   <!-- 1. For each link... -->
   for (var i = 0; i < document.links.length; i++) {

      <!-- 1.1. Ignore "mailto" -->
      if (document.links[i].href.indexOf("mailto") != -1) {
         continue;
      }

      <!-- 1.2. Ignore internal reference links -->
      if (document.links[i].href.indexOf("#") == 0) {
         continue;
      }

      <!-- 1.3. Ignore javascript links -->
      if (document.links[i].href.indexOf("javascript:") != -1) {
         continue;
      }

      document.links[i].href = svr + 
                               "<%= strURI %>/redirect.jsp?replace=" +
                               document.links[i].href +
                               "&tid=" + tid +
                               "&linkid=" + i;
   }
}


<!--                                           -->
<!-- Proxy href links so that we can save them -->
function proxyForms() {
   var svr     = '<%= strSvrA    %>';
   var tid     = '<%= nextTID    %>';

   <!-- 1. For each form... -->
   for (var i = 0; i < document.forms.length; i++) {
      document.forms[i].action = svr +
                                 "<%= strURI %>/redirect.jsp?replace=" +
                                 document.forms[i].action +
                                 "&tid=" + tid;
   }

}



</script>

<%--                                                                        --%>
<%--  --------------------------------------------------------------------- --%>
<%--                                                                        --%>
<%
   ////
   //// This chunk of code just reads in a URL and spits it back out.
   ////
   URL                  url;
   HttpURLConnection    conn = null;
   InputStream          istream;
   InputStreamReader    istreamRdr;
   BufferedReader       bufRdr;
   int                  responseCode = -1;
   String               str;
   StringBuffer         strbuf = new StringBuffer();

   //// 0. Don't follow redirects.
   ////    Do it manually, since the redirected URL value
   ////    doesn't seem to be returned to us.
   HttpURLConnection.setFollowRedirects(false);

   //// 1. Read in the URL.
   try {
      //// 1.1. Open up the connection.
      url = new URL(strReplace);

      try {
         conn = (HttpURLConnection) url.openConnection();
      }
      catch (Exception e) {
      }

      responseCode = conn.getResponseCode();

      //// 1.2. If we have an error, get the error input stream.
      ////      Otherwise, just use the normal input stream.
      if (responseCode >= 400) {
         istream = conn.getErrorStream();
         if (istream == null) {
            istream = conn.getInputStream();
         }
      }
      else {
         istream = conn.getInputStream();
      }

      //// 1.3. Read in all of the data.
      strbuf = WebQuiltLib.readAllFromInputStream(istream);

      //// 1.4. Put the data into the HTML.
      out.println(strbuf);
   }
   catch (Exception e) {
      out.println("<PRE>");
      e.printStackTrace(new PrintWriter(out));
      out.println("</PRE>");
   }


   //// 2. Save the HTML file and log the page.
   try {
      HttpServletRequest req         = (HttpServletRequest) request;
      String             strBaseName = "webquilt-" + req.getSession().getId();
      FileWriter         fwtr;

      //// 2.1. Save the file locally.
      ////      First create the directory.
      File fileSaveDir = new File(strBaseName);
      if (!fileSaveDir.exists()) {
         fileSaveDir.mkdir();
      }
      fwtr = new FileWriter(strBaseName + "/" + nextTID + ".html");
      fwtr.write("<BASE HREF=\"" + strBase + "\">\n");
      fwtr.write(strbuf.toString());
      fwtr.close();


      //// 2.2. Log the page.
      fwtr = new FileWriter(strBaseName + ".txt", true);
      fwtr.write((System.currentTimeMillis() - dTime.longValue()) + "\t" + 
                  strFromTID + " " +
                  nextTID    + "\t" +
                  responseCode + " " +
                  strLinkID  + " " + strReplace + "\n");
      fwtr.close();
   }
   catch (Exception e) {
      e.printStackTrace();
   }

%>
